home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / dtype / txtdt392.lha / textdtpatch / textdtpatch.c < prev    next >
C/C++ Source or Header  |  1995-11-13  |  17KB  |  717 lines

  1. /*
  2. ** $PROJECT: text.datatype patch
  3. **
  4. ** $VER: textdtpatch.c 39.2 (11.11.95)
  5. **
  6. ** by
  7. **
  8. ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
  9. **
  10. ** (C) Copyright 1995
  11. ** All Rights Reserved !
  12. **
  13. ** $HISTORY:
  14. **
  15. ** 11.11.95 : 039.002 : added pattern and case insensetive support
  16. ** 04.07.95 : 039.001 : initial
  17. */
  18.  
  19.  
  20. /*FS*//* ----------------------------- version data ----------------------------- */
  21. /* $STARTDEFINE: "BumpRev defines"*/
  22. #define VERSION  39
  23. #define REVISION 2
  24. #define DATE "11.11.95"
  25. #define VERS "textdtpatch 39.2"
  26. #define VSTRING "textdtpatch 39.2 (11.11.95)\r\n"
  27. #define VERSTAG "\0$VER: textdtpatch 39.2 (11.11.95)"
  28. #define NAME "textdtpatch"
  29. /* $ENDDEFINE:   */
  30. /*FE*/
  31.  
  32. /*FS*//* ------------------------------- autodoc -------------------------------- */
  33. /*GB*** textdtpatch **********************************************************
  34. *
  35. *    NAME
  36. *        textdtpatch - patches the text.datatype to support search method
  37. *
  38. *    VERSION
  39. *        39.2
  40. *
  41. *    TEMPLATE
  42. *        none
  43. *
  44. *    REQUIREMENT
  45. *        reqtools.library V38, OS3.0 or higher
  46. *
  47. *    FUNCTION
  48. *        This program patches the text.datatype, so that the new one can
  49. *        search for a string. Now it can search by four different ways :
  50. *        1. case sensetive match like strncmp(). Button "Case".
  51. *        2. case insensetive match like Strnicmp(). Button "NoCase".
  52. *        3. case sensetive pattern using MatchPattern(). Button "Pattern".
  53. *        4. case insensetive pattern  using MatchPatternNoCase().
  54. *           Button "PatternNoCase".
  55. *        The following key commands are supported :
  56. *
  57. *        Return (STM_ACTIVATE_FIELD) - opens a reqtools requester to enter
  58. *            the search string and searches for that if confirmed.
  59. *
  60. *        Tab (STM_NEXT_FIELD) , '>' (STM_BROWSE_NEXT) searches for the next
  61. *            occurrence of the string.
  62. *
  63. *        Shift-Tab (STM_PREV_FIELD) , '<' (STM_BROWSE_PREV) searches for the
  64. *            previous occurrence of the string.
  65. *
  66. *    INSTALLATION
  67. *        1. Copy textdtpatch to your c: or anywhere you like.
  68. *        2. Add in your S:User-Startup following line:
  69. *           run >nil: c:textdtpatch
  70. *        3. To terminate textdtpatch send a break (Ctrl-C).
  71. *
  72. *    SEE ALSO
  73. *        text.datatype
  74. *
  75. *    AUTHOR
  76. *        Stefan Ruppert
  77. *        Windthorststrasse 5
  78. *        65439 Floersheim Main
  79. *        GERMANY
  80. *        EMail: ruppert@goofy.zdv.uni-mainz.de
  81. *               i511@informatik.fh-wiesbaden.de
  82. *        WWW:   http://www.uni-mainz.de/~ruppert/
  83. *
  84. *****************************************************************************/
  85. /*FE*/
  86.  
  87. /*FS*//* ------------------------------- include -------------------------------- */
  88.  
  89. #include <exec/types.h>
  90. #include <exec/memory.h>
  91.  
  92. #include <clib/alib_protos.h>
  93. #include <clib/utility_protos.h>
  94. #include <clib/dos_protos.h>
  95. #include <clib/dtclass_protos.h>
  96. #include <clib/exec_protos.h>
  97. #include <clib/intuition_protos.h>
  98.  
  99. #include <pragmas/utility_pragmas.h>
  100. #include <pragmas/dos_pragmas.h>
  101. #include <pragmas/dtclass_pragmas.h>
  102. #include <pragmas/exec_sysbase_pragmas.h>
  103. #include <pragmas/intuition_pragmas.h>
  104.  
  105. #include <dos/dostags.h>
  106. #include <datatypes/textclass.h>
  107.  
  108. #include <clib/reqtools_protos.h>
  109. #include <pragmas/reqtools.h>
  110. #include <libraries/reqtools.h>
  111.  
  112. #include <string.h>
  113. /*FE*/
  114.  
  115. /*FS*//* ------------------------- register defintions -------------------------- */
  116.  
  117. #define RegCall      __asm
  118. #define GetA4        __saveds
  119.  
  120. #define REGA0        register __a0
  121. #define REGA1        register __a1
  122. #define REGA2        register __a2
  123. /*FE*/
  124.  
  125. /*FS*//* -------------------------- debug definitions --------------------------- */
  126.  
  127. #ifdef DEBUG
  128. #define bug      kprintf
  129. extern void bug(char *fmt,...);
  130.  
  131. #define D(x)     x
  132. #define DB(x)   { bug(__FILE__ "(%4ld):" __FUNC__ "() :",__LINE__); \
  133.                         bug x; \
  134.                      }
  135. #else
  136. #define bug
  137. #define D(x)
  138. #define DB(x)
  139. #endif
  140. /*FE*/
  141.  
  142. /*FS*//* -------------------------- static data items --------------------------- */
  143.  
  144. static const STRPTR version = VERSTAG;
  145. /*FE*/
  146.  
  147. /*FS*//* ------------------------------ prototypes ------------------------------ */
  148.  
  149. RegCall GetA4 ULONG mytextdtdispatcher(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg);
  150. ULONG DoAsyncMethod(Class *cl,Object *obj,Msg msg,ULONG tag1,...);
  151. ULONG DoAsyncMethodA(Class *cl,Object *obj,Msg msg,struct TagItem *tagList);
  152. ULONG NotifyAttrs(Object * obj, void * ginfo, ULONG flags, ULONG tag1,...);
  153.  
  154. ULONG getstring(Class *cl,Object *obj,struct dttGetString *msg);
  155. LONG strseg(struct SegCmp *,struct Line *line);
  156. LONG striseg(struct SegCmp *,struct Line *line);
  157. LONG patseg(struct SegCmp *,struct Line *line);
  158. ULONG searchstring(Class *cl,Object *obj,LONG direction,struct dttSearchText *msg);
  159. /*FE*/
  160.  
  161. /*FS*//* ------------------------------ definition ------------------------------ */
  162.  
  163. #define TRG(msg)           ((struct dtTrigger *) (msg))
  164. #define SM(msg)            ((struct dttGetString *) (msg))
  165.  
  166. #define DTTM_GETSTRING     0x20000
  167. #define DTTM_SEARCHNEXT    0x20001
  168. #define DTTM_SEARCHPREV    0x20002
  169.  
  170. struct ClassData
  171. {
  172.     struct Library *cd_SysBase;
  173.     struct Library *cd_DOSBase;
  174.     struct Library *cd_IntuitionBase;
  175.     struct Library *cd_UtilityBase;
  176. };
  177.  
  178.  
  179. struct dttGetString
  180. {
  181.     ULONG MethodID;
  182.     struct GadgetInfo dttgs_GInfo;
  183.     LONG dttgs_SearchMethod;
  184. };
  185.  
  186. #define DTTSTM_CASE           1
  187. #define DTTSTM_NOCASE         2
  188. #define DTTSTM_PATTERN        3
  189. #define DTTSTM_PATTERN_NOCASE 4
  190. #define DTTSTM_MAX            5
  191.  
  192. struct dttSearchText
  193. {
  194.     ULONG MethodID;
  195.     struct GadgetInfo *dttst_GInfo;
  196.     STRPTR dttst_Text;
  197.     LONG dttst_TextLen;
  198.     LONG dttst_Mode;
  199. };
  200.  
  201. #define BUFFER_SIZE     128
  202.  
  203. struct MyTextDTData
  204. {
  205.     LONG FoundLine;
  206.     LONG LastMode;
  207.     struct dttGetString Msg;
  208.     UBYTE Buffer[BUFFER_SIZE];
  209.     UBYTE PatBuffer[BUFFER_SIZE];
  210.     UBYTE TempBuffer[BUFFER_SIZE];
  211. };
  212.  
  213. struct SegCmp
  214. {
  215.     struct ClassData *sc_ClassData;
  216.     struct MyTextDTData *sc_InstanceData;
  217.     STRPTR sc_String;
  218.     LONG sc_StringLen;
  219.     STRPTR sc_Buffer;
  220. };
  221.  
  222. typedef LONG (*CMPSEG)(struct SegCmp *,struct Line *);
  223.  
  224. #define IntuitionBase      cd->cd_IntuitionBase
  225. #define DOSBase            cd->cd_DOSBase
  226. #define UtilityBase        cd->cd_UtilityBase
  227. /*FE*/
  228.  
  229. /*FS*//* --------------------------- main entry point --------------------------- */
  230. GetA4 int main(void)
  231. {
  232.     struct Library *SysBase = *((struct Library **) 4L);
  233.     struct ClassData *cd;
  234.  
  235.     if(SysBase->lib_Version < 39)
  236.         return(RETURN_FAIL);
  237.  
  238.     if((cd = AllocVec(sizeof(struct ClassData), MEMF_CLEAR | MEMF_ANY)))
  239.     {
  240.         struct Library *DTClassBase;
  241.  
  242.         cd->cd_SysBase = SysBase;
  243.  
  244.         DOSBase       = OpenLibrary("dos.library",39);
  245.         IntuitionBase = OpenLibrary("intuition.library",39);
  246.         UtilityBase   = OpenLibrary("utility.library",39);
  247.  
  248.         if((DTClassBase = OpenLibrary("datatypes/text.datatype",39)))
  249.         {
  250.             struct IClass *TextDTClass;
  251.  
  252.             if((TextDTClass = ObtainEngine()))
  253.             {
  254.                 struct IClass *MyTextDTClass;
  255.                 ClassID oldclassid;
  256.  
  257.                 oldclassid = TextDTClass->cl_ID;
  258.                 TextDTClass->cl_ID = "org_text.datatype";
  259.  
  260.                 if((MyTextDTClass = MakeClass("text.datatype",NULL,TextDTClass,sizeof(struct MyTextDTData),0)))
  261.                 {
  262.                     MyTextDTClass->cl_Dispatcher.h_Entry = (HOOKFUNC) mytextdtdispatcher;
  263.                     MyTextDTClass->cl_UserData = (ULONG) cd;
  264.  
  265.                     AddClass(MyTextDTClass);
  266.  
  267.                     Wait(SIGBREAKF_CTRL_C);
  268.  
  269.                     RemoveClass(MyTextDTClass);
  270.  
  271.                     while(!FreeClass(MyTextDTClass))
  272.                         Delay(50);
  273.  
  274.                 } else
  275.                     Printf("can't make new text.datatype class !\n");
  276.  
  277.                 TextDTClass->cl_ID = oldclassid;
  278.  
  279.             } else
  280.                 Printf("can't obtain old text.datatype class !\n");
  281.  
  282.             CloseLibrary(DTClassBase);
  283.         } else
  284.             Printf("can't open text.datatype !\n");
  285.  
  286.         CloseLibrary(IntuitionBase);
  287.         CloseLibrary(DOSBase);
  288.  
  289.         FreeVec(cd);
  290.     }
  291.  
  292.     return(RETURN_OK);
  293. }
  294. /*FE*/
  295.  
  296. /*FS*/ ULONG DoAsyncMethod(Class *cl,Object *obj,Msg msg,ULONG tag1,...)
  297. {
  298.     return(DoAsyncMethodA(cl,obj,msg,(struct TagItem *) &tag1));
  299. }
  300. /*FE*/
  301. /*FS*/ /*"ULONG DoAsyncMethodA(Class *cl,Object *obj,Msg msg,struct TagItem *tagList)"*/
  302.  
  303. struct AsyncMethodMsg
  304. {
  305.     struct Message amm_ExecMessage;
  306.     Object *amm_Object;
  307.     Msg amm_Msg;
  308. };
  309.  
  310. RegCall GetA4 ULONG asyncmethodfunc(void)
  311. {
  312.     struct Library *SysBase = *((struct Library **) 4L);
  313.     struct Process *proc = (struct Process *) FindTask(NULL);
  314.     Object *obj;
  315.     Msg msg;
  316.     struct AsyncMethodMsg *amsg;
  317.  
  318.     WaitPort(&proc->pr_MsgPort);
  319.     amsg = (struct AsyncMethodMsg *) GetMsg(&proc->pr_MsgPort);
  320.     obj = amsg->amm_Object;
  321.     msg = amsg->amm_Msg;
  322.     ReplyMsg(&amsg->amm_ExecMessage);
  323.  
  324.     D(bug("recieved object : %lx, msg : %lx\n",obj,msg));
  325.  
  326.     return(DoMethodA(obj,msg));
  327. }
  328.  
  329. #define SysBase         cd->cd_SysBase
  330.  
  331. ULONG DoAsyncMethodA(Class *cl,Object *obj,Msg msg,struct TagItem *tagList)
  332. {
  333.     struct ClassData *cd = (struct ClassData *) cl->cl_UserData;
  334.     struct AsyncMethodMsg amsg;
  335.     struct Process *proc = NULL;
  336.     struct MsgPort *mport;
  337.  
  338.     DB(("before CreateMsgPort() !\n"));
  339.  
  340.     if((mport = CreateMsgPort()))
  341.     {
  342.  
  343.         DB(("after CreateMsgPort() !\n"));
  344.  
  345.         amsg.amm_Object = obj;
  346.         amsg.amm_Msg    = msg;
  347.  
  348.         amsg.amm_ExecMessage.mn_Node.ln_Type = NT_MESSAGE;
  349.         amsg.amm_ExecMessage.mn_ReplyPort    = mport;
  350.  
  351.         DB(("before CreateNewProcTags() !\n"));
  352.  
  353.         if((proc = CreateNewProcTags(NP_Entry,asyncmethodfunc,
  354.                                               (tagList) ? TAG_MORE : TAG_IGNORE,tagList,
  355.                                               TAG_DONE)))
  356.         {
  357.             DB(("sending object : %lx, msg : %lx\n",obj,msg));
  358.  
  359.             PutMsg(&proc->pr_MsgPort,&amsg.amm_ExecMessage);
  360.             WaitPort(mport);
  361.         }
  362.  
  363.         DeleteMsgPort(mport);
  364.     }
  365.     return((ULONG) proc);
  366. }
  367. /*FE*/
  368. /*FS*/ ULONG NotifyAttrs(Object * obj, void * ginfo, ULONG flags, ULONG tag1,...)
  369. {
  370.      return(DoMethod(obj, OM_NOTIFY, &tag1, ginfo, flags));
  371. }
  372. /*FE*/
  373.  
  374. /*FS*/ ULONG getstring(Class *cl,Object *obj,struct dttGetString *msg)
  375. {
  376.     struct MyTextDTData *data = INST_DATA(cl,obj);
  377.     struct ClassData *cd = (struct ClassData *) cl->cl_UserData;
  378.     struct GadgetInfo *ginfo = &msg->dttgs_GInfo;
  379.     struct Library *ReqToolsBase;
  380.     ULONG retval = 0;
  381.  
  382.     DB(("before getstring() !\n"));
  383.  
  384.     if((ReqToolsBase = OpenLibrary("reqtools.library",38)))
  385.     {
  386.         retval = rtGetString(data->Buffer,sizeof(data->Buffer),
  387.                                     "Text Datatype Search String",NULL,
  388.                                     RT_Window     ,ginfo->gi_Window,
  389.                                     RT_ReqPos     ,REQPOS_CENTERWIN,
  390.                                     RT_LockWindow ,TRUE,
  391.                                     RT_Underscore , '_',
  392.                                     RTGS_GadFmt   ,"C_ase|_NoCase|_Pattern|PatternN_oCase|_Cancel",
  393.                                     TAG_DONE);
  394.  
  395.         CloseLibrary(ReqToolsBase);
  396.  
  397.         if(retval)
  398.         {
  399.             data->LastMode = retval;
  400.             Forbid();
  401.             DoMethod(obj,msg->dttgs_SearchMethod,ginfo,data->Buffer,strlen(data->Buffer),retval);
  402.             Permit();
  403.         }
  404.     }
  405.  
  406.     return(retval);
  407. }
  408. /*FE*/
  409.  
  410. /*FS*/ LONG strseg(struct SegCmp *cmp,struct Line *line)
  411. {
  412.     STRPTR text = line->ln_Text;
  413.     STRPTR str  = cmp->sc_String;
  414.     STRPTR ptr;
  415.     LONG slen = cmp->sc_StringLen;
  416.     LONG llen = line->ln_TextLen;
  417.     LONG len;
  418.  
  419.     while(llen >= slen)
  420.     {
  421.         ptr = str;
  422.         len = slen;
  423.  
  424.         while(*text == *ptr)
  425.         {
  426.             text++;
  427.             ptr++;
  428.             llen--;
  429.             len--;
  430.         }
  431.  
  432.         if(len==0)
  433.             return(1);
  434.         else
  435.         {
  436.             text++;
  437.             llen--;
  438.         }
  439.     }
  440.     return(0);
  441. }
  442. /*FE*/
  443. /*FS*/ LONG striseg(struct SegCmp *cmp,struct Line *line)
  444. {
  445.     struct ClassData *cd = cmp->sc_ClassData;
  446.     STRPTR text = line->ln_Text;
  447.     STRPTR ptr;
  448.     LONG slen = cmp->sc_StringLen;
  449.     LONG llen = line->ln_TextLen;
  450.     LONG len;
  451.  
  452.     while(llen >= slen)
  453.     {
  454.         ptr = cmp->sc_String;
  455.         len = slen;
  456.  
  457.         while(ToUpper(*text) == *ptr)
  458.         {
  459.             text++;
  460.             ptr++;
  461.             llen--;
  462.             len--;
  463.         }
  464.  
  465.         if(len==0)
  466.             return(1);
  467.         else
  468.         {
  469.             text++;
  470.             llen--;
  471.         }
  472.     }
  473.     return(0);
  474. }
  475. /*FE*/
  476. /*FS*/ LONG patseg(struct SegCmp *cmp,struct Line *line)
  477. {
  478.     struct ClassData *cd = cmp->sc_ClassData;
  479.     LONG len = line->ln_TextLen;
  480.  
  481.     if(len > BUFFER_SIZE - 1)
  482.         len = BUFFER_SIZE - 1;
  483.     strncpy(cmp->sc_Buffer,line->ln_Text,line->ln_TextLen);
  484.     cmp->sc_Buffer[len] = 0;
  485.  
  486.     return(MatchPattern(cmp->sc_String,cmp->sc_Buffer));
  487. }
  488. /*FE*/
  489. /*FS*/ LONG patiseg(struct SegCmp *cmp,struct Line *line)
  490. {
  491.     struct ClassData *cd = cmp->sc_ClassData;
  492.     LONG len = line->ln_TextLen;
  493.  
  494.     if(len > BUFFER_SIZE - 1)
  495.         len = BUFFER_SIZE - 1;
  496.     strncpy(cmp->sc_Buffer,line->ln_Text,line->ln_TextLen);
  497.     cmp->sc_Buffer[len] = 0;
  498.  
  499.     return(MatchPatternNoCase(cmp->sc_String,cmp->sc_Buffer));
  500. }
  501. /*FE*/
  502.  
  503. /*FS*/ ULONG searchstring(Class *cl,Object *obj,LONG direction,struct dttSearchText *msg)
  504. {
  505.     struct ClassData *cd = (struct ClassData *) cl->cl_UserData;
  506.     struct MyTextDTData *data = INST_DATA(cl,obj);
  507.  
  508.     struct List *list;
  509.     struct SegCmp segcmp;
  510.  
  511.     CMPSEG cmpfuncs[DTTSTM_MAX] = {strseg,striseg,patseg,patiseg};
  512.     CMPSEG cmp;
  513.  
  514.     LONG mode = msg->dttst_Mode;
  515.  
  516.     segcmp.sc_ClassData    = cd;
  517.     segcmp.sc_InstanceData = data;
  518.     segcmp.sc_String       = msg->dttst_Text;
  519.     segcmp.sc_StringLen    = msg->dttst_TextLen;
  520.     segcmp.sc_Buffer       = data->TempBuffer;
  521.  
  522.     switch(msg->dttst_Mode)
  523.     {
  524.     case DTTSTM_PATTERN_NOCASE:
  525.         {
  526.             LONG test;
  527.             if((test = ParsePatternNoCase(msg->dttst_Text,data->PatBuffer,BUFFER_SIZE)) == 1)
  528.             {
  529.                 segcmp.sc_String = data->PatBuffer;
  530.                 break;
  531.             } else if(test != 0)
  532.             {
  533.                 mode = 0;
  534.                 break;
  535.             } else
  536.                 mode = DTTSTM_NOCASE;
  537.         }
  538.     case DTTSTM_NOCASE:
  539.         {
  540.             STRPTR ptr  = data->PatBuffer;
  541.             STRPTR text = msg->dttst_Text;
  542.             while((*ptr++ = ToUpper(*text++)));
  543.             segcmp.sc_String = data->PatBuffer;
  544.         }
  545.         break;
  546.     case DTTSTM_PATTERN:
  547.         switch(ParsePattern(msg->dttst_Text,data->PatBuffer,BUFFER_SIZE))
  548.         {
  549.         case 1:
  550.             segcmp.sc_String = data->PatBuffer;
  551.             break;
  552.         case 0:
  553.             mode = DTTSTM_CASE;
  554.             break;
  555.         default:
  556.             mode = 0;
  557.         }
  558.         break;
  559.     }
  560.  
  561.     if(mode > 0 && mode <= DTTSTM_MAX)
  562.     {
  563.         cmp = cmpfuncs[mode-1];
  564.  
  565.         DB(("search for : \"%s\" !\n",msg->dttst_Text));
  566.  
  567.         if(GetAttr(TDTA_LineList,obj,(ULONG *) &list))
  568.         {
  569.             struct Line *line;
  570.             LONG len = msg->dttst_TextLen;
  571.             LONG found = data->FoundLine;
  572.             LONG y = 0;
  573.  
  574.             strcpy(data->TempBuffer,msg->dttst_Text);
  575.  
  576.             line = (struct Line *) list->lh_Head;
  577.  
  578.             if(direction == -1)
  579.                 found--;
  580.  
  581.             while(y <= found && line->ln_Link.mln_Succ)
  582.             {
  583.                 if(line->ln_Flags & LNF_LF)
  584.                     y++;
  585.                 line = (struct Line *) line->ln_Link.mln_Succ;
  586.             }
  587.  
  588.             found = -1;
  589.  
  590.             if(direction == -1)
  591.             {
  592.                 if(line->ln_Link.mln_Pred)
  593.                     line = (struct Line *) line->ln_Link.mln_Pred;
  594.  
  595.                 while(line->ln_Link.mln_Pred && found == -1)
  596.                 {
  597.                     if(line->ln_Flags & LNF_LF)
  598.                         y--;
  599.  
  600.                     if(line->ln_TextLen >= len)
  601.                     {
  602.                         if(cmp(&segcmp,line))
  603.                         {
  604.                             found = y;
  605.                             break;
  606.                         }
  607.                     }
  608.                     line = (struct Line *) line->ln_Link.mln_Pred;
  609.                 }
  610.             } else
  611.             {
  612.                 while(line->ln_Link.mln_Succ && found == -1)
  613.                 {
  614.                     if(line->ln_TextLen >= len)
  615.                     {
  616.                         if(cmp(&segcmp,line))
  617.                         {
  618.                             found = y;
  619.                             break;
  620.                         }
  621.                     }
  622.                     if(line->ln_Flags & LNF_LF)
  623.                         y++;
  624.                     line = (struct Line *) line->ln_Link.mln_Succ;
  625.                 }
  626.             }
  627.  
  628.             if(found < 0)
  629.             {
  630.                 DisplayBeep(msg->dttst_GInfo->gi_Screen);
  631.                 if(data->FoundLine >= 0)
  632.                     NotifyAttrs(obj,msg->dttst_GInfo,0,DTA_TopVert,data->FoundLine,TAG_DONE);
  633.             } else
  634.             {
  635.                 data->FoundLine = found;
  636.                 NotifyAttrs(obj,msg->dttst_GInfo,0,DTA_TopVert,found,TAG_DONE);
  637.             }
  638.         }
  639.     }
  640.     return(0);
  641. }
  642. /*FE*/
  643.  
  644. /*FS*/ RegCall GetA4 ULONG mytextdtdispatcher(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
  645. {
  646.     struct MyTextDTData *data = INST_DATA(cl,obj);
  647.     ULONG retval = 0;
  648.  
  649.     switch(msg->MethodID)
  650.     {
  651.     case OM_NEW:
  652.         {
  653.             Object *newobj;
  654.  
  655.             if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
  656.             {
  657.                 data = INST_DATA(cl,newobj);
  658.  
  659.                 data->FoundLine = -1;
  660.                 data->LastMode  = 1;
  661.  
  662.                 DB(("new text.datatype object : %lx\n",newobj));
  663.  
  664.                 retval = (ULONG) newobj;
  665.             }
  666.         }
  667.         break;
  668.     case DTM_TRIGGER:
  669.         {
  670.             ULONG searchmethod = DTTM_SEARCHNEXT;
  671.  
  672.             switch(TRG(msg)->dtt_Function)
  673.             {
  674.             case STM_PREV_FIELD:
  675.             case STM_BROWSE_PREV:
  676.                 searchmethod = DTTM_SEARCHPREV;
  677.             case STM_NEXT_FIELD:
  678.             case STM_BROWSE_NEXT:
  679.                 if(data->Buffer[0])
  680.                 {
  681.                     DoMethod(obj,searchmethod,TRG(msg)->dtt_GInfo,data->Buffer,strlen(data->Buffer),data->LastMode);
  682.                     break;
  683.                 }
  684.             case STM_ACTIVATE_FIELD:
  685.  
  686.                 data->Msg.MethodID           = DTTM_GETSTRING;
  687.                 /* copy the full GadgetInfo, because this request is asyncron and datatypes
  688.                  * creates this structure on the stack (Oh No) !
  689.                  */
  690.                 data->Msg.dttgs_GInfo        = *TRG(msg)->dtt_GInfo;
  691.                 data->Msg.dttgs_SearchMethod = searchmethod;
  692.  
  693.                 DB(("before async method !\n"));
  694.  
  695.                 DoAsyncMethod(cl,obj,(Msg) &data->Msg,NP_Name,"text.datatype getstring process",TAG_DONE);
  696.                 break;
  697.             }
  698.         }
  699.         break;
  700.     case DTTM_GETSTRING:
  701.         retval = getstring(cl,obj,(struct dttGetString *) msg);
  702.         break;
  703.     case DTTM_SEARCHNEXT:
  704.         retval = searchstring(cl,obj,1,(struct dttSearchText *) msg);
  705.         break;
  706.     case DTTM_SEARCHPREV:
  707.         retval = searchstring(cl,obj,-1,(struct dttSearchText *) msg);
  708.         break;
  709.     default:
  710.         retval = DoSuperMethodA(cl,obj,msg);
  711.     }
  712.  
  713.     return(retval);
  714. }
  715. /*FE*/
  716.  
  717.